<template>
  <div class="go-board-container">
    <div v-if="!hideGameInfo" class="game-info">
      <div class="player-info">
        <div
          class="player black"
          :class="{ active: currentPlayer === 'black' }"
        >
          黑方
          <div class="stone black"></div>
          <div class="captures">提子: {{ blackCaptures }}</div>
        </div>
        <div
          class="player white"
          :class="{ active: currentPlayer === 'white' }"
        >
          白方
          <div class="stone white"></div>
          <div class="captures">提子: {{ whiteCaptures }}</div>
        </div>
      </div>
      <div class="controls">
        <button @click="pass">虚着</button>
        <button @click="reset">重新开始</button>
      </div>
    </div>

    <div
      class="board"
      :style="{ width: boardSize * cellSize + 'px', height: boardSize * cellSize + 'px' }"
    >
      <!-- 绘制棋盘网格线 -->
      <div
        v-for="i in boardLines"
        :key="'h' + i"
        class="line horizontal"
        :style="{ top: (i - 1) * cellSize + 'px', width: boardSize * cellSize + 'px' }"
      ></div>
      <div
        v-for="i in boardLines"
        :key="'v' + i"
        class="line vertical"
        :style="{ left: (i - 1) * cellSize + 'px', height: boardSize * cellSize + 'px' }"
      ></div>

      <!-- 绘制星位 -->
      <div
        v-for="point in starPoints"
        :key="point.x + '-' + point.y"
        class="star-point"
        :style="{
          left: point.x * cellSize + 'px',
          top: point.y * cellSize + 'px',
        }"
      ></div>

      <!-- 绘制棋子 -->
      <div v-for="(row, y) in board" :key="'row-' + y" class="board-row">
        <div
          v-for="(cell, x) in row"
          :key="x + '-' + y"
          class="intersection"
          :style="{
            left: x * cellSize + 'px',
            top: y * cellSize + 'px',
            width: cellSize + 'px',
            height: cellSize + 'px',
          }"
          @click="placeStone(x, y)"
        >
          <div
            v-if="cell !== null"
            class="stone"
            :class="cell"
            :style="{
              width: stoneSize + 'px',
              height: stoneSize + 'px',
            }"
          ></div>
        </div>
      </div>
    </div>

    <div v-if="gameOver" class="game-over">
      <div class="message">游戏结束</div>
      <div class="result">{{ gameResult }}</div>
      <button @click="reset">再来一局</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'GoBoard',
  props: {
    boardSize: {
      type: Number,
      default: 19,
      validator: (value) => [9, 13, 19].includes(value)
    },
    hideGameInfo: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      cellSize: 30, // 每个格子的大小
      stoneSize: 28, // 棋子大小
      board: [], // 棋盘状态
      currentPlayer: 'black', // 当前玩家
      previousBoard: null, // 上一步棋盘状态，用于检测打劫
      blackCaptures: 0, // 黑方提子数
      whiteCaptures: 0, // 白方提子数
      passCount: 0, // 连续虚着次数
      gameOver: false, // 游戏是否结束
      gameResult: '', // 游戏结果
      starPoints: [] // 星位点
    }
  },
  computed: {
    boardLines() {
      return this.boardSize;
    },
  },
  created() {
    this.initBoard();
    this.initStarPoints();
  },
  methods: {
    // 初始化棋盘
    initBoard() {
      this.board = Array(this.boardSize)
        .fill()
        .map(() => Array(this.boardSize).fill(null));
      this.currentPlayer = "black";
      this.previousBoard = null;
      this.blackCaptures = 0;
      this.whiteCaptures = 0;
      this.passCount = 0;
      this.gameOver = false;
      this.gameResult = "";
    },

    // 初始化星位点
    initStarPoints() {
      // 9路棋盘的星位
      if (this.boardSize === 9) {
        this.starPoints = [
          { x: 2, y: 2 },
          { x: 2, y: 6 },
          { x: 4, y: 4 },
          { x: 6, y: 2 },
          { x: 6, y: 6 },
        ];
      }
      // 13路棋盘的星位
      else if (this.boardSize === 13) {
        this.starPoints = [
          { x: 3, y: 3 },
          { x: 3, y: 9 },
          { x: 6, y: 6 },
          { x: 9, y: 3 },
          { x: 9, y: 9 },
        ];
      }
      // 19路棋盘的星位
      else {
        this.starPoints = [
          { x: 3, y: 3 },
          { x: 3, y: 9 },
          { x: 3, y: 15 },
          { x: 9, y: 3 },
          { x: 9, y: 9 },
          { x: 9, y: 15 },
          { x: 15, y: 3 },
          { x: 15, y: 9 },
          { x: 15, y: 15 },
        ];
      }
    },

    // 落子
    placeStone(x, y) {
      // 如果游戏已结束或该位置已有棋子，则不能落子
      if (this.gameOver || this.board[y][x] !== null) {
        return;
      }

      // 保存当前棋盘状态用于检测打劫
      const previousBoard = JSON.parse(JSON.stringify(this.board));

      // 落子
      this.board[y][x] = this.currentPlayer;

      // 检查提子
      const capturedStones = this.checkCaptures(x, y);

      // 如果没有提子，检查自杀规则
      if (capturedStones === 0) {
        const group = this.findGroup(x, y);
        if (this.countLiberties(group) === 0) {
          // 自杀，恢复棋盘
          this.board = previousBoard;
          return;
        }
      }

      // 检查打劫规则
      if (
        this.previousBoard &&
        this.isBoardEqual(this.board, this.previousBoard)
      ) {
        // 打劫，恢复棋盘
        this.board = previousBoard;
        return;
      }

      // 保存当前棋盘状态
      this.previousBoard = previousBoard;

      // 切换玩家
      this.currentPlayer = this.currentPlayer === "black" ? "white" : "black";
      this.$emit('player-changed', this.currentPlayer);

      // 重置连续虚着计数
      this.passCount = 0;
    },

    // 检查提子
    checkCaptures(x, y) {
      const opponent = this.currentPlayer === "black" ? "white" : "black";
      let capturedCount = 0;

      // 检查四个方向的邻接点
      const directions = [
        { dx: 1, dy: 0 },
        { dx: -1, dy: 0 },
        { dx: 0, dy: 1 },
        { dx: 0, dy: -1 },
      ];

      for (const dir of directions) {
        const nx = x + dir.dx;
        const ny = y + dir.dy;

        // 检查是否在棋盘范围内
        if (nx >= 0 && nx < this.boardSize && ny >= 0 && ny < this.boardSize) {
          // 如果是对手的棋子
          if (this.board[ny][nx] === opponent) {
            const group = this.findGroup(nx, ny);
            if (this.countLiberties(group) === 0) {
              // 提子
              for (const stone of group) {
                this.board[stone.y][stone.x] = null;
                capturedCount++;
              }
            }
          }
        }
      }

      // 更新提子数
      if (this.currentPlayer === "black") {
        this.blackCaptures += capturedCount;
        this.$emit('update-captures', { player: 'black', captures: this.blackCaptures });
      } else {
        this.whiteCaptures += capturedCount;
        this.$emit('update-captures', { player: 'white', captures: this.whiteCaptures });
      }

      return capturedCount;
    },

    // 查找一个棋子所在的连通棋子组
    findGroup(x, y) {
      const color = this.board[y][x];
      if (color === null) return [];

      const visited = Array(this.boardSize)
        .fill()
        .map(() => Array(this.boardSize).fill(false));
      const group = [];

      const dfs = (x, y) => {
        if (
          x < 0 ||
          x >= this.boardSize ||
          y < 0 ||
          y >= this.boardSize ||
          visited[y][x] ||
          this.board[y][x] !== color
        ) {
          return;
        }

        visited[y][x] = true;
        group.push({ x, y });

        dfs(x + 1, y);
        dfs(x - 1, y);
        dfs(x, y + 1);
        dfs(x, y - 1);
      };

      dfs(x, y);
      return group;
    },

    // 计算一个棋子组的气
    countLiberties(group) {
      const liberties = new Set();

      for (const stone of group) {
        const { x, y } = stone;
        const directions = [
          { dx: 1, dy: 0 },
          { dx: -1, dy: 0 },
          { dx: 0, dy: 1 },
          { dx: 0, dy: -1 },
        ];

        for (const dir of directions) {
          const nx = x + dir.dx;
          const ny = y + dir.dy;

          if (
            nx >= 0 &&
            nx < this.boardSize &&
            ny >= 0 &&
            ny < this.boardSize &&
            this.board[ny][nx] === null
          ) {
            liberties.add(`${nx},${ny}`);
          }
        }
      }

      return liberties.size;
    },

    // 比较两个棋盘状态是否相同
    isBoardEqual(board1, board2) {
      for (let y = 0; y < this.boardSize; y++) {
        for (let x = 0; x < this.boardSize; x++) {
          if (board1[y][x] !== board2[y][x]) {
            return false;
          }
        }
      }
      return true;
    },

    // 虚着
    pass() {
      if (this.gameOver) return;

      this.passCount++;
      this.currentPlayer = this.currentPlayer === "black" ? "white" : "black";

      // 如果连续两次虚着，游戏结束
      if (this.passCount >= 2) {
        this.endGame();
      }
    },

    // 结束游戏
    endGame() {
      this.gameOver = true;

      // 简单计算结果（仅基于提子数）
      if (this.blackCaptures > this.whiteCaptures) {
        this.gameResult = `黑方胜（提子差：${
          this.blackCaptures - this.whiteCaptures
        }）`;
      } else if (this.whiteCaptures > this.blackCaptures) {
        this.gameResult = `白方胜（提子差：${
          this.whiteCaptures - this.blackCaptures
        }）`;
      } else {
        this.gameResult = "平局";
      }
    },

    // 重置游戏
    reset() {
      this.initBoard();
    },
  },
};
</script>

<style scoped>
.go-board-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  margin: 20px auto;
  font-family: "Arial", sans-serif;
}

.game-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 15px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  margin-bottom: 25px;
}

.player-info {
  display: flex;
  gap: 30px;
}

.player {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
  border-radius: 5px;
  transition: all 0.3s;
}

.player.active {
  background-color: #f0f0f0;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}

.controls {
  display: flex;
  gap: 10px;
}

button {
  padding: 8px 16px;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s;
}

button:hover {
  background-color: #45a049;
}

.board {
  position: relative;
  background-color: #DCB35C; /* 更自然的木质色调 */
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23DCB35C" /><rect width="100" height="100" fill="%23C9A048" opacity="0.1" /></svg>');
  border: 4px solid #8B5A2B; /* 更深的边框颜色 */
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4), inset 0 0 60px rgba(139, 90, 43, 0.2);
  margin: 20px 0;
  border-radius: 4px;
  overflow: hidden; /* 确保内容不会溢出边框 */
}

.line {
  position: absolute;
  background-color: rgba(0, 0, 0, 0.7); /* 稍微透明一点的线条 */
  z-index: 1;
}

.horizontal {
  height: 1.5px; /* 稍微粗一点的线条 */
}

.vertical {
  width: 1.5px; /* 稍微粗一点的线条 */
}

.star-point {
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.8);
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
  z-index: 2;
  /* 调整星位点的位置，使其正确显示在交叉点上 */
  transform: translate(-50%, -50%);
}

.intersection {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  z-index: 3;
  /* 确保点击区域居中在交叉点上 */
  transform: translate(-50%, -50%);
  /* 调整点击区域大小，使其更容易点击 */
  box-sizing: border-box;
}

.stone {
  border-radius: 50%;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.4);
  /* 移除transition效果，防止棋子乱动 */
  /* 确保棋子居中在交叉点上 */
  position: absolute;
  transform: translate(-50%, -50%);
  /* 添加!important确保样式不被覆盖 */
  left: 50% !important;
  top: 50% !important;
}

.stone.black {
  background-color: #000;
  background: radial-gradient(circle at 30% 30%, #555, #222 40%, #000 80%);
  border: 1px solid #000;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.6), inset 0 -2px 3px rgba(255, 255, 255, 0.2), inset 0 2px 3px rgba(255, 255, 255, 0.3);
}

.stone.white {
  background-color: #fff;
  background: radial-gradient(circle at 30% 30%, #fff, #f5f5f5 40%, #eee 80%);
  border: 1px solid #ccc;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4), inset 0 -2px 3px rgba(0, 0, 0, 0.05), inset 0 2px 3px rgba(255, 255, 255, 0.9);
}

/* 移除hover效果，防止鼠标滑过时棋子乱动 */
.intersection:hover .stone {
  /* 保持棋子稳定，不随鼠标移动而变化 */
  transform: translate(-50%, -50%);
}

.player .stone {
  width: 20px;
  height: 20px;
  margin: 5px 0;
}

.captures {
  font-size: 14px;
  margin-top: 5px;
}

.game-over {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(255, 255, 255, 0.9);
  padding: 20px;
  border-radius: 10px;
  text-align: center;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
  z-index: 10;
}

.message {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 10px;
}

.result {
  font-size: 18px;
  margin-bottom: 20px;
}
</style>
